#ifndef __demo_test_pobo_client_work_h__
#define __demo_test_pobo_client_work_h__

#include <qserver/event.hpp>
#include <testpobo/xml_parser.hpp>
using qserv::event;
namespace testpobo
{
    class client_work
    {
    public:
        typedef qserv::NetConnection<client_work> server_handler_type;

        client_work(LoggerPtr logger, boost::shared_ptr<CXmlParser> parser, utils::TrafficWatchPtr trafficWatch):
            m_recvBuf(2048),
            m_logger(logger),
            m_parser(parser),
            m_trafficWatch(trafficWatch)
        {
        }

        void on_clear(server_handler_type& handler)
        {
        }

        void on_open(server_handler_type& handler)
        {
            boost::asio::socket_base::reuse_address optionReuseAddr(true);
            handler.socket().set_option(optionReuseAddr);
            boost::asio::socket_base::receive_buffer_size optionRecvBuf(0);
            handler.socket().set_option(optionRecvBuf);
            m_id = tlgettid();
            unsigned short localport = handler.socket().local_endpoint().port();
            unsigned short peerport = handler.socket().remote_endpoint().port();
            string localaddr(handler.socket().local_endpoint().address().to_string());
            string peeraddr(handler.socket().remote_endpoint().address().to_string());
            LOG4CXX_INFO(m_logger, boost::format("[Client%5%] [%1%:%2%] <--- [%3%:%4%] created") % peeraddr % peerport % localaddr % localport % m_id);
            handler.async_read_some(boost::asio::buffer(&m_recvBuf[0], 2048));
        }

        void on_read(server_handler_type& handler, std::size_t bytes_transferred)
        {
            m_trafficWatch->watch("Traffic Watch", bytes_transferred);
            string content((char *)&m_recvBuf[0], bytes_transferred);
            m_parser->parse(content);
            //LOG4CXX_INFO(m_logger, content.c_str());
            handler.async_read_some(boost::asio::buffer(&m_recvBuf[0], 2048));
        }

        void on_write(server_handler_type& handler, std::size_t bytes_transferred)
        {

        }

        void on_close(server_handler_type& handler, const boost::system::error_code& e)
        {
            m_recvBuf.clear();
            m_recvBuf.resize(2048);
            switch (e.value())
            {
                // Operation successfully completed.
            case 0:
            case boost::asio::error::eof:
                LOG4CXX_INFO(m_logger, boost::format("[Client%2%] Peer close connection : %1%")% e.message() % m_id);
                break;

                // Connection breaked.
            case boost::asio::error::connection_aborted:
            case boost::asio::error::connection_reset:
            case boost::asio::error::connection_refused:
                LOG4CXX_INFO(m_logger, boost::format("[Client%2%] Peer connection exception : %1%")% e.message() % m_id);
                break;

                // Other error.
            case boost::asio::error::timed_out:
                LOG4CXX_INFO(m_logger, boost::format("[Client%2%] Peer connection expired : %1%")% e.message() % m_id);
                break;
            case boost::asio::error::no_buffer_space:
            default:
                LOG4CXX_INFO(m_logger, boost::format("[Client%2%] ERROR : %1%") % e.message() % m_id);
                break;
            }
        }

        void on_parent(server_handler_type& handler, boost::shared_ptr<event> event)
        {
        }

        void on_child(server_handler_type& handler, boost::shared_ptr<event> event)
        {
        }

    private:
        ByteArray                      m_recvBuf;
        LoggerPtr                      m_logger;
        TLUint64                       m_id;
        boost::shared_ptr<CXmlParser>  m_parser;
        utils::TrafficWatchPtr         m_trafficWatch;
    };
}

#endif // __demo_test_pobo_client_work_h__
